﻿using Serilog.Events;
using Serilog;
using SL.NET.Core.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;

namespace WCS.Application
{
   public class LogHelper
    {

        /// <summary>
        /// 记录异常日志
        /// </summary>
        /// <param name="fileName">方法名</param>
        /// <param name="ex">异常错误</param>
        public static void WriteErrorLog(string fileName, Exception ex)
        {
            try
            {
                var user = StaticHttpContext.User;
                var api = StaticHttpContext.API;
                var ip = StaticHttpContext.IP;
                var domain = StaticHttpContext.Domain;
                var traceIdentifier = StaticHttpContext.TraceIdentifier;
                var threadId = Environment.CurrentManagedThreadId.ToString();
                var dateTimeNow = DateTime.Now;

                //Task.Run(() =>
                //{
                #region 根据接口、用户控制开关
                if (!App.GetConfig<string>("Serilog:Error:Enabled").GetCBool())
                    return;
                // 过滤用户
                if (!App.GetConfig<string>("Serilog:Error:AllowAllUsers").GetCBool()
                    && !App.GetConfig<List<string>>("Serilog:Error:AllowUsers").Contains(user)
                    && App.GetConfig<List<string>>("Serilog:Error:IgnoreUsers").Contains(user))
                {
                    return;
                }
                // 过滤接口
                if (!App.GetConfig<string>("Serilog:Error:AllowAllApis").GetCBool()
                    && !App.GetConfig<List<string>>("Serilog:Error:AllowAPIs").Contains(api)
                    && App.GetConfig<List<string>>("Serilog:Error:IgnoreApis").Contains(api))
                {
                    return;
                }
                #endregion


                LoggerConfiguration logger = new LoggerConfiguration()
                        .MinimumLevel.Debug()
                        .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
                            .Enrich.WithProperty("Datetime", dateTimeNow)
                            .Enrich.WithProperty("TraceIdentifier", traceIdentifier)  // 跟踪日志中的请求的唯一标识符
                            .Enrich.WithProperty("ThreadId", threadId) // 线程id
                    ;

                #region 写本地文件

                var writeToFileEnable = App.GetConfig<string>("Serilog:WriteToFile:Enabled").GetCBool();
                if (writeToFileEnable)
                {
                    string filePath = App.GetConfig<string>("Serilog:Info:Path").GetCString() == "" ? AppContext.BaseDirectory + "/log" : App.GetConfig<string>("Serilog:Info:Path").GetCString();
                    if (fileName.ToLower() != "recordaccesslogs")
                        fileName = $"{api.Trim('/').Replace("/", "_")}-{user}-{fileName}";
                    if (fileName.StartsWith("--"))
                    {
                        fileName = fileName.Replace("--", "");
                    }

                    Log.Logger = new LoggerConfiguration()
                        .MinimumLevel.Debug()
                        .MinimumLevel.Override("Microsoft", LogEventLevel.Error)
                        .WriteTo
                        .Async(a =>
                            a.File(Path.Combine(filePath, DateTime.Now.ToString("yyyyMMdd"), fileName + ".log"),
                            rollingInterval: RollingInterval.Infinite,
                            outputTemplate: "{Datetime:yyyy-MM-dd HH:mm:ss.ffffff} [{Level:u3}] [{TraceIdentifier}] [{ThreadId}] {Message}{NewLine}{Exception}"
                        ))
                        .CreateLogger();

                    //Log.Error(ex, " --- " + ex.Message);
                    Log.Error(ex, "{Exception}", " --- " + ex.Message);
                    Log.CloseAndFlush();


                }
                #endregion



            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }

    }
}
